# Virtual Router Simulator 
#
# Copyright (C) 2009-2010 VRSim Project
# Author: Choonho Son <choonho@kt.com>
# URL: <http://vrsim.googlecode.com>
# For license information, see LICENSE.TXT
#

import uuid
import sys
import os

"""
try:
    import libvirt
except:
    import VRSim.proxy_libvirt as libvirt
"""
import VRSim.proxy_libvirt as libvirt
import subprocess as sub
import commands

from xml.dom.minidom import parseString

from VRSim.Globals import Adapter
import VRSim.Globals as globals
from VRSim.Utils import debug,  message
from VRSim.Node.XML import XML
#from VRSim.Node.VMAPIClient import VMAPIClient
from VRSim.Node.Interface import Interface
from VRSim.Ui.Config import Config

# QEMU(KVM) class for management
# The elements are based on http://www.libvirt.org/formatdomain.html 
class Domain(XML):
    def __init__(self,  type="kvm",  vnc=False,  nodeid=None):
        
        XML.__init__(self, "domain")
        #VMAPIClient.__init__(self, nodeid)
        # General metadata
        self.dom = None         
        self.type = type
        self.type_list = [ "kvm", "qemu"]
        # name is primary key of domain
        self.uuid = str(uuid.uuid4())
        self.name = "None"
        
        # Basic resources
        self.memory = "262144"
        self.currrentMemory = "262144"
        self.vcpu = "1"
        
        # Operating system booting
        self.os = OS()
        
        # Lifecycle control
        self.on_poweroff = "destroy"
        self.on_reboot = "restart"
        self.on_crash = "restart"
        
        # Hypervisor features
        self.features = features()
        
        # Time keeping
        self.clock = None
        self.clock_list = ["utc",  "localtime"]
        
        # devices member
        self.opend_Console = False
        self.vnc = vnc
        self.devices = devices(vnc=vnc,  nodeid=nodeid)
        
        
        ###########
        # for Console
        ###########
        self.console = None
        
        ###############
        # for shutdown
        ###############
        self.domid = None
        self.pid = None
     
    def makeUniqueName(self):
        """ name must globally unique
        """
        print "Nodeid in makeUniqueName",  self.nodeid
        userid = globals.GApp.userid
        nodename = globals.GApp.topology.getNodeName(self.nodeid)
        name = "%s_%s" % (userid,nodename) 
        #temp = self.uuid.split("-")
        print name
        return name
        
        #temp = self.uuid.split("-")
        #return temp[0]
     
    
        
    ########################
    # XML
    ########################
    def getXML(self):
        #<domain type='kvm'>
        # <name>routerA</name>
        # <uuid>xxx</uuid>
        # <memory>xxx</memory>
        # <vcpu>1</vcpu>
        domain = self.xml.createElement("domain")
        domain.setAttribute("type",  self.type)
        name = self.xml.createElement("name")
        #nameText = self.xml.createTextNode(str(self.name))
        nameText = self.xml.createTextNode(str(self.makeUniqueName()))
        name.appendChild(nameText)
        uuid = self.xml.createElement("uuid")
        uuidText = self.xml.createTextNode(self.uuid)
        uuid.appendChild(uuidText)
        memory = self.xml.createElement("memory")
        memoryText = self.xml.createTextNode(self.memory)
        memory.appendChild(memoryText)
        vcpu = self.xml.createElement("vcpu")
        vcpuText = self.xml.createTextNode(str(self.vcpu))
        vcpu.appendChild(vcpuText)
        domain.appendChild(name)
        domain.appendChild(uuid)
        domain.appendChild(memory)
        domain.appendChild(vcpu)
        #OS
        os = self.os.getXML()
        domain.appendChild(os)
        
        on_poweroff = self.xml.createElement("on_poweroff")
        on_poweroffText  = self.xml.createTextNode(self.on_poweroff)
        on_poweroff.appendChild(on_poweroffText)
        on_reboot = self.xml.createElement("on_reboot")
        on_rebootText = self.xml.createTextNode(self.on_reboot)
        on_reboot.appendChild(on_rebootText)
        on_crash = self.xml.createElement("on_crash")
        on_crashText = self.xml.createTextNode(self.on_crash)
        on_crash.appendChild(on_crashText)
        
        domain.appendChild(on_poweroff)
        domain.appendChild(on_reboot)
        domain.appendChild(on_crash)
        
        #features
        features = self.features.getXML()
        domain.appendChild(features)
        
        #clock
        clock = self.xml.createElement("clock")
        clock.setAttribute("offset",  str(self.clock))
        
        #devices
        devices = self.devices.getXML()
        domain.appendChild(devices)
        
        return domain
    

    def setXML(self,  domain):
        debug("### Called domain XML ###")
        #<domain type='kvm'>            self.type
        # <name>routerA</name>      self.name
        # <uuid>xxx</uuid>                self.uuid
        # <memory>xxx</memory>    self.memory
        # <vcpu>1</vcpu>                  self.vcpu
        self.type = domain.getAttribute("type")
        node_name = domain.getElementsByTagName("name")[0]
        self.name = node_name.firstChild.data
        node_uuid = domain.getElementsByTagName("uuid")[0]
        self.uuid = node_uuid.firstChild.data
        node_memory = domain.getElementsByTagName("memory")[0]
        self.memory = node_memory.firstChild.data
        node_vcpu = domain.getElementsByTagName("vcpu")[0]
        self.vcpu = node_vcpu.firstChild.data
        
        # OS node
        node_os = domain.getElementsByTagName("os")[0]
        self.os.setXML(node_os)
        
        # <on_poweroff>destroy</on_poweroff>
        # <on_reboot>restart</on_reboot>
        # <on_crash>restart</on_crash>
        node_on_poweroff = domain.getElementsByTagName("on_poweroff")[0]
        self.on_poweroff = node_on_poweroff.firstChild.data
        node_on_reboot = domain.getElementsByTagName("on_reboot")[0]
        self.on_reboot = node_on_reboot.firstChild.data
        node_on_crash = domain.getElementsByTagName("on_crash")[0]
        self.on_reboot = node_on_crash.firstChild.data
        
        # Feature node
        node_features = domain.getElementsByTagName("features")[0]
        self.features.setXML(node_features)
         
        # devices
        node_devices = domain.getElementsByTagName("devices")[0]
        self.devices.setXML(node_devices)
        
    def filterToQEMU(self,  dom):
        """
        change domain information to QEMU domain format
        return domain
        """
        # delete slot & port in interface
        interfaces = dom.getElementsByTagName("interface")
        for interface in interfaces:
            interface.removeAttribute("slot")
            interface.removeAttribute("port")
        return dom
        
        
    def start(self,  vm):
        # check disk image is exist?
        vminst = globals.GApp.topology.getVMAPI(self.nodeid)
        hdd = self.devices.hdd.source
        if not vminst.exists(hdd):
            msg = "HDD image(%s) does not exist" % hdd
            message(msg,  "critical")
            
            node = globals.GApp.topology.nodes[self.nodeid]
            cfg = Config(node.physnode,  page="HardDisk")
            cfg.show()
            cfg.exec_()
            return False
            
        # start virtual machine
        # find URL by vm
        hypervisors = globals.GApp.topology.hypervisors
        for hypervisor in hypervisors:
            name = hypervisor[0]
            if name == vm:
                url = hypervisor[2]
        
        try:
            conn = libvirt.open(url)
            # get XML object
            domain = self.getXML()
            # filter to QEMU
            dom = self.filterToQEMU(domain)
        
            xml = dom.toxml()
            self.dom = conn.defineXML(xml)
            tf = self.dom.create()
                        
            if tf == True:
                msg = globals.eventMsg["start"]
                nmsg = msg % globals.GApp.topology.getNodeName(self.nodeid)
                globals.GApp.mainWindow.NodesLog.addEvent(nmsg)
                return True
            else:
                msg = globals.errorMsg["start"]
                nmsg = msg % globals.GApp.topology.getNodeName(self.nodeid)
                globals.GApp.mainWindow.NodesLog.addError(nmsg)
                return False 
        except:
            msg = globals.errorMsg["start"]
            nmsg = msg % globals.GApp.topology.getNodeName(self.nodeid)
            globals.GApp.mainWindow.NodesLog.addError(nmsg)
            return False
            
        
        
        
    def stop(self):
        try:
            tf = self.dom.shutdown()
                        
            if tf == True:
                msg = globals.eventMsg["stop"]
                nmsg = msg % globals.GApp.topology.getNodeName(self.nodeid)
                globals.GApp.mainWindow.NodesLog.addEvent(nmsg)
                return True
            else:
                msg = globals.errorMsg["stop"]
                nmsg = msg % globals.GApp.topology.getNodeName(self.nodeid)
                globals.GApp.mainWindow.NodesLog.addError(nmsg)
                return False 
                
        
        except:
            msg = globals.errorMsg["stop"]
            nmsg = msg % globals.GApp.topology.getNodeName(self.nodeid)
            globals.GApp.mainWindow.NodesLog.addError(nmsg)
            return False
            
    def suspend(self):
        try:
            tf = self.dom.suspend()
            if tf == True:
                msg = globals.eventMsg["stop"]
                nmsg = msg % globals.GApp.topology.getNodeName(self.nodeid)
                globals.GApp.mainWindow.NodesLog.addEvent(nmsg)
                return True
            else:
                msg = globals.errorMsg["stop"]
                nmsg = msg % globals.GApp.topology.getNodeName(self.nodeid)
                globals.GApp.mainWindow.NodesLog.addError(nmsg)
                return False 
            
        except:
            debug("Suspend failed")
            return False
      
    def getPID(self):
        """ return proess ID of virtual node
        pid file: /usr/local/var/run/libvirt/qemu/<name>.pid
        This is effect, when client run on  single 
        """
        uri = "/usr/local/var/run/libvirt/qemu/" + self.name + ".pid"
        try:
            fp = open(uri,  'r')
            pid = fp.read()
            fp.close()
            return pid
        except:
            return None
        
    def openConsole(self):
        
        debug("openConsole")
        """ 
        if self.vnc == True:
            debug("Open Windows")
            open_cmd = "virt-viewer -c qemu:///system " + str(self.name)
            sub.Popen(open_cmd,  shell=True,  close_fds=True)
            return
        """
        if self.devices.vnc:
            """ open by vnc
            """
            
            path = globals.VNC
            
            # VNC command
            cmd = "%s %s:%s"  % (path,  self.devices.console_ip,  self.devices.console)
            #cmd = "%s" % (term)
            print "VNC command:",  cmd
            
                
            proc = sub.Popen(cmd,  shell=True)
            if proc:
                return True
            return False 
                    
        if self.devices.console:
            if sys.platform.startswith('win'):
                # windows platform
                # with VNC
                
                """ open by putty
                """
                path = globals.TERMINAL
                path_split = path.split("/")
                
                #os.chdir(base_dir)
                term = path_split[-1]
                npath = unicode(path).encode(globals.ENCODING)
                
                
                if term == "putty.exe":
                    # putty command
                    cmd = "%s telnet://%s:%s/" % (npath,  self.devices.console_ip,  self.devices.console)
                elif term == "ttermpro.exe":
                    # teraterm command
                    cmd = "%s telnet://%s:%s  /T=0 /W=%s" % (npath,  self.devices.console_ip,  self.devices.console,  self.hostname)
                else:
                    cmd = "%s" % (path)
                #cmd = "start telnet %s %s" % (self.devices.console_ip,  self.devices.console)
                sub.Popen(cmd,  shell=False)
            elif sys.platform.startswith('linux'):
                # linux platform
                cmd = "telnet %s %s" % (self.devices.console_ip,  self.devices.console)
                sub.Popen("xterm -T " + self.hostname + " -e '" + cmd + "' >  /dev/null 2>&1 &",  shell = True,  close_fds=True)
        return
        
#######################
# sub class for domain
#######################
class OS(XML):
    def __init__(self,  type="hvm", loader=None,  boot="hd" ):
        self.type = type
        self.loader = loader
        self.boot = boot
        self.kernel = None
        self.initrd = None
        self.cmdline = None
        
        XML.__init__(self, "os")
        
    def getXML(self):
        os = self.xml.createElement("os")
        type = self.xml.createElement("type")
        typeText = self.xml.createTextNode(self.type)
        type.appendChild(typeText)
        os.appendChild(type)
        if self.loader:
            loader = self.xml.createElement("loader")
            loaderText = self.xml.createTextNode(self.loader)
            os.appendChild(loader)
        if self.boot:
            boot = self.xml.createElement("boot")
            boot.setAttribute("dev",  self.boot)
            os.appendChild(boot)
            
        return os
         
    def setXML(self,  os):
        # bios boot loader
        #<os>
        #  <type>hvm</type>
        #  <loader>/usr/lib/xen/boot/hvmloader</loader>
        #  <boot dev='hd'/>
        #</os>
    
        # Host boot loader
        #<os>
        #  <type>hvm</type>
        #  <loader>/usr/lib/xen/boot/hvmloader</loader>
        #  <kernel>/root/f8-i386-vmlinuz</kernel>
        #  <initrd>/root/f8-i386-initrd</initrd>
        #  <cmdline>console=ttyS0 ks=http://example.com/f8-i386/os/</cmdline>
        #</os>
        node_type = os.getElementsByTagName("type")[0]      # mandatory
        self.type = node_type.firstChild.data
        node_loader = os.getElementsByTagName("loader")  
        node_boot = os.getElementsByTagName("boot")
        # for hostname bootloader
        node_kernel = os.getElementsByTagName("kernel")
        node_initrd = os.getElementsByTagName("initrd")
        node_cmdline = os.getElementsByTagName("cmdline")
        
        if node_loader:
            self.loader = node_loader[0].firstChild.data
        if node_boot:
            self.boot = node_boot[0].getAttribute("dev")
        if node_kernel:
            self.kernel = node_kernel[0].firstChild.data
        if node_initrd:
            self.initrd = node_initrd[0].firstChild.data
        if node_cmdline:
            self.cmdline = node_cmdline[0].firstChild.data
            
        
class features(XML):
    def __init__(self, pae = False,  acpi = True,  apic = False ):
        self.pae = pae
        self.acpi = acpi
        self.apic = apic
        XML.__init__(self, 'features')
        
    def getXML(self):
        features = self.xml.createElement("features")
        if self.pae:
            pae = self.xml.createElement("pae")
            features.appendChild(pae)
        if self.acpi:
            acpi = self.xml.createElement("acpi")
            features.appendChild(acpi)
        if self.apic:
            apic = self.xml.createElement("apic")
            features.appendChild(apic)
        return features
       
    def setXML(self,  node_feature):
    #<features>
        # <pae/>
        # <acpi/>
        # <apic/>
        #</features>
        node_pae = node_feature.getElementsByTagName("pae")
        node_acpi = node_feature.getElementsByTagName("acpi")
        node_apic = node_feature.getElementsByTagName("apic")
        if node_pae:
            self.pae = True
        else:
            self.pae = False
        if node_acpi:
            self.acpi = True
        else:
            self.acpi = False
        if node_apic:
            self.apic = True
        else:
            self.apic = False
            
#######################
# devices
#######################
class devices(XML):
    def __init__(self,  vnc=False,  nodeid=None):
        self.nodeid = nodeid
        self.emulator = "/usr/local/bin/qemu-system-x86_64"
        self.hdd = disk()
        
        self.hasCDROM = False
        self.cdrom = disk(device="cdrom")
        self.hasFloopy = False
        self.floopy = disk(device="floopy")
        self.MAX_SLOT = 8
        
        self.slot = {
                     'slot 0': {"adapter": ["i82559er",  1], 
                                0 :  Interface(0, 0,  enabled=True) }, 
                     'slot 1': {"adapter": ["i82559er",  1], 
                                0 :  Interface(1, 0,  enabled=True) }, 
                     'slot 2': {"adapter": ["i82559er",  1],
                                0 :  Interface(2, 0,  enabled=True) }, 
                     'slot 3': {"adapter": ["i82559er",  1],  
                                0 : Interface(3, 0,  enabled=True) }, 
                     'slot 4': {"adapter": ["i82559er",  1], 
                                0 : Interface(4, 0) }, 
                     'slot 5': {"adapter": ["i82559er",  1], 
                                0 : Interface(5, 0) }, 
                     'slot 6': {"adapter": ["i82559er",  1], 
                                0 : Interface(6, 0) }, 
                     'slot 7': {"adapter": ["i82559er",  1], 
                                0 : Interface(7, 0) }, 
                     }
        # VNC viewer
        self.vnc = vnc
        # console (ip, port)
        self.console_ip = "127.0.0.1"
        self.console = globals.dynamips_console
        globals.dynamips_console += 1
        # XML
        XML.__init__(self,  "devices")
 
    def getUnusedInterfaces(self,  linktype):
        """ return unused interfaces' dictionary
        return format
        'slot 0' : ['FastEthernet 0/1']
        'slot 1' : ['FastEthernet 1/1', 'FastEthernet 1/2']
        p.s. return same linktype of interface
        """
        # ex) linktype == globals.Enum.LinkType.Ethernet
        bandwidth = globals.bandWidth[linktype]
        adapterList = self.getAdapterFromBandwidth(bandwidth)
        # TEST
        print "getUnusedInterfaces adpaterList:",  bandwidth,  adapterList
        slotNames = self.slot.keys()
        slotNames.sort()
        # return value
        result = {}
        for slotName in slotNames:
            content = self.slot[slotName]
            # get adapter
            adapterContent = content["adapter"]
            adapter = adapterContent[0]
            maxIf = adapterContent[1]
            for possibleAdapter in adapterList:
                if adapter == possibleAdapter:
                    # adpater is matched
                    # find unused Interfaces of slot X
                    unusedIf = []
                    for portNumber in range(maxIf):
                        interfaceInstance = content[portNumber]
                        isEnabled = interfaceInstance.isEnabled
                        isAssigned = interfaceInstance.isAssigned
                        if isEnabled and (not isAssigned):
                            unusedIf.append(interfaceInstance.name)
                    # add unused Intefaces
                    if len(unusedIf) > 0:
                        result[slotName] = unusedIf
        if len(result.keys()) == 0:
            msg = "There is no unused Interface!"
            message(msg,  "warning")
            debug(msg)
            return False
            
        return result
    
    def getPossibleAdapter(self,  slot=0):
        """ return adapter and max interface
        return value is dictionary
        """
        # QEMU model
        return {"rtl8139" : 1,
                      "i82559er" : 1, 
                      "e1000" : 1}
    
       
    def getPossiblePorts(self,  slotName):
        ports = self.slot[slotName]
        adapter = ports["adapter"]
        length = adapter[1]
        result = []
        for i in range(length):
            interface = ports[i]
            result.append(interface.name)
            
        return result
        
     
    def getInterface(self,  sn,  pn):
        # param: ex) sn = 1, pn = 2
        # return interface instance
        sname = "slot " + str(sn)
        ports = self.slot[sname]
        interface = ports[int(pn)]
        return interface
        
     
    def getAdapterFromBandwidth(self,  bandWidth):
        if bandWidth == "E":
            return ["rtl8139"]
        elif bandWidth == "FE":
            return ["i82559er"]
        elif bandWidth == "GE":
            return ["e1000"]
        else:
            return ["rtl8139"]
        
    def isAssigned(self,  slotN,  portN):
        """ return interface is assigned or not
        """
        interface = self.getInterface(slotN,  portN)
        return interface.isAssigned
        
    def getBlankSlotNPort(self,  bandwidth):
        """ find first blank slot and port
        return: [slot number, port number]
                ex) [0, 2]
        """
        badapters = self.getAdapterFromBandwidth(bandwidth)
        
        slotNames = self.slot.keys()
        slotNames.sort()
        for slotName in slotNames:
            
            ports = self.slot[slotName]
            
            # find Bandwidth is same
            searchTF = False
            for badapter in badapters:
                if badapter == ports["adapter"][0]:
                    searchTF = True
            if searchTF == False:
                continue
            
            maxInterface = ( ports["adapter"] )[1]
            for port in range(maxInterface):
                interface = ports[port]
                if interface.isEnabled == True and interface.isAssigned == False:
                    print interface.slot,  interface.port
                    return [interface.slot,  interface.port]
        
        # not found
        # There is no blank interface
        # overwirte is needed
        return [0, 0]
     
    def updateNic(self,  sindex, pindex,   srcPort,  dstPort,  delay):
        """ update Network Interface card
        sindex = slot Index
        pindex = port Index
        1) set Assigned
        2) update Internal Link (srcPort, dstPort)
        """
        interface = self.getInterface(sindex,  pindex)
        interface.setAssigned()
        interface.setInternal(srcPort,  dstPort,  delay)
        
    def changeAdapter(self,  slotN,  nadapter):
        slotName = "slot " + str(slotN)
        slot = self.slot[slotName]
        adapter = slot["adapter"]
        adapter[0] = nadapter
        adapter[1] = Adapter.MaxInterface[nadapter]
        for i in range(adapter[1]):
            interface = self.slot[i]
            interface.changeAdapter(nadapter)
            
    def clearInterface(self,  ifName):
        # windows name
        if str(ifName) == "eth 0":
            ifName = "fxp 0"
        (slotN,  portN) = self.getSlotNPortByName(ifName)
        
        if slotN == None:
            return False
        
        interface = self.getInterface(slotN,  portN)
        interface.setClear()
        
        
    def getSlotNPortByName(self,  ifName):
        if ifName == "eth 0":
            ifName = "fxp 0"
        keys = self.slot.keys()
        keys.sort()
        slotN = 0
        for slotName in keys:
            slot = self.slot[slotName]
            adapter = slot['adapter']
            for portN in range(adapter[1]):
                interface = slot[portN]
                debug(interface.name,  "Inteface name:")
                if interface.name == str(ifName):
                    return (slotN,  portN)
            slotN = slotN + 1
        return None
            
            
        
    ############################
    # XML
    ############################
    def getXML(self):
        devices = self.xml.createElement("devices")
        emulator = self.xml.createElement("emulator")
        emulatorText =self.xml.createTextNode(self.emulator)
        emulator.appendChild(emulatorText)
        hdd = self.hdd.getXML()
        
        # TODO: cdrom check
        #cdrom = self.cdrom.getXML()
        
        # appendChild
        devices.appendChild(emulator)
        devices.appendChild(hdd)
        # TODO: append cdrom
        #devices.appendChild(cdrom)
        
        # NIC
        keys = self.slot.keys()
        keys.sort()
        for slotName in keys:
            slot = self.slot[slotName]
            adapter = slot['adapter']
            maxInterface = adapter[1]
            for i in range(maxInterface):
                interface = slot[i]
                if interface.isEnabled == False:
                    continue
                xml = interface.getXML()
                devices.appendChild(xml)
        
        # Graphics (GUI Windows)
        #<graphics type='vnc' listen='xxx.xxx.xxx.xxx' port='xx'/>
        if self.vnc == True:
            vnc = self.xml.createElement("input")
            vnc.setAttribute("type",  "tablet")
            vnc.setAttribute("bus",  "usb")
            graphics = self.xml.createElement("graphics")
            # find remote VM's IP
            self.console_ip = globals.GApp.topology.getVMAPIIP(self.nodeid)
            graphics.setAttribute("type",  "vnc")
            graphics.setAttribute("listen",  self.console_ip)
            graphics.setAttribute("port",  str(self.console))
            graphics.setAttribute("autoport",  "no")
            graphics.setAttribute("keymap", "en-us")
            
            devices.appendChild(vnc)
            devices.appendChild(graphics)
        
        # Console connection
        #<console type='tcp'>
        #<source mode='bind' host='127.0.0.1' service='8001'/>
        #<protocol type='raw'/>
        #<target port='0'/>
        #</console>
        else:
            console = self.xml.createElement("console")
            console.setAttribute("type", "tcp")
            source = self.xml.createElement("source")
            source.setAttribute("mode",  "bind")
            # find remote VM's IP
            self.console_ip = globals.GApp.topology.getVMAPIIP(self.nodeid)
            source.setAttribute("host",  self.console_ip)
            #######################################
            # console port is dynamically allocated
            #######################################
            source.setAttribute("service",  str(self.console) )
            protocol = self.xml.createElement("protocol")
            #protocol.setAttribute("type",  "raw")
            protocol.setAttribute("type",  "telnet")
            target = self.xml.createElement("target")
            target.setAttribute("port", "0")
            console.appendChild(source)
            console.appendChild(protocol)
            console.appendChild(target)
            devices.appendChild(console)
            
        return devices
        
    def setXML(self,  devices):
        #self.emulator = "/usr/local/bin/qemu-system-x86_64"
        #self.hdd = disk()
        #self.hasCDROM = True
        #self.cdrom = disk(device="cdrom")
        #self.hasFloopy = False
        #self.floopy = disk(device="floopy")
        node_emulator = devices.getElementsByTagName("emulator")[0]
        self.emulator = node_emulator.firstChild.data
        disks = devices.getElementsByTagName("disk")
        
        # Disks
        for disk in disks:
            device_list = disk.getAttribute("device")
            if device_list == "disk":
                self.hdd.setXML(disk)
            elif device_list == "cdrom":
                self.cdrom.setXML(disk)
            elif device_list == "floopy":
                self.floopy.setXML(disk)
            else:
                debug("Unkown devices : ")
                debug(self.disk.toprettyxml())
                pass
        
        # Network Interface Cards
        interfaces = devices.getElementsByTagName("interface")
        for interface in interfaces:
            slot = interface.getAttribute("slot")
            port = interface.getAttribute("port")
            interfaceInstance = self.getInterface(slot,  port)
            interfaceInstance.model = "qemu"
            interfaceInstance.setXML(interface)
        
        
class disk(XML):
    def __init__(self,  type="file",  device="disk",  source = globals.junos_9_0):
        self.type= type
        self.type_list = ["file", "block"]
        self.device = device
        self.device_list = ["floopy",  "disk",  "cdrom"]
        if self.device == "disk":
            self.source = source
        else:
            self.source = None
        self.source_hd_list = globals.junos_img_list
        self.target_dev = 'hda'
        self.target_bus = 'ide'
        
        XML.__init__(self,  "disk")
        
    def getXML(self):
        disk = self.xml.createElement("disk")
        disk.setAttribute("type",  str(self.type))
        disk.setAttribute("device",  str(self.device))
        
        if self.type == "file":
            source = self.xml.createElement("source")
            source.setAttribute("file",  str(self.source))
            disk.appendChild(source)
            
        target = self.xml.createElement("target")
        target.setAttribute("dev",  str(self.target_dev))
        target.setAttribute("bus",  str(self.target_bus))
        disk.appendChild(target)
        
        return disk
        
    def setXML(self,  disk):
        """ disk : floopy, disk, cdrom
        <disk type='file' device='disk'>
        <driver name="tap" type="aio">
        <source file='/var/lib/xen/images/fv0'/>
        <target dev='hda' bus='ide'/>
        </disk>
        self.type
        self.device = device
        self.source = globals.junos_9_0
        self.target_dev = 'hda'
        self.target_bus = 'ide'
        """
        self.type = disk.getAttribute("type")
        self.device = disk.getAttribute("device")
        
        node_driver = disk.getElementsByTagName("driver")
        node_source = disk.getElementsByTagName("source")
        node_target = disk.getElementsByTagName("target")
        
        # file device
        if self.type == "file" and node_source and node_target:
            self.source = node_source[0].getAttribute("file")
            self.target_dev = node_target[0].getAttribute("dev")
            self.target_bus = node_target[0].getAttribute("bus")
        
        
